home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
OLE2BOOK.ZIP
/
CHAP13.ZIP
/
PATRON
/
IOLECONT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-19
|
11KB
|
420 lines
/*
* IOLECONT.CPP
*
* Implementation of the IOleItemContainer interface for Patron's CPage
* and CPatronDoc alike, using the constructor parameter fDoc to differentiate.
*
* Copyright (c)1993 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Software Design Engineer
* Microsoft Systems Developer Relations
*
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include <stdlib.h>
#include "patron.h"
/*
* CImpIOleItemContainer::CImpIOleItemContainer
* CImpIOleItemContainer::~CImpIOleItemContainer
*
* Parameters (Constructor):
* pObj LPVOID of the page or pages.
* punkOuter LPUNKNOWN to which we delegate.
* fDoc BOOL indicating if we're in CPatronDoc or CPage
*/
CImpIOleItemContainer::CImpIOleItemContainer(LPVOID pObj
, LPUNKNOWN punkOuter, BOOL fDoc)
{
m_cRef=0;
m_fDoc=fDoc;
if (fDoc)
{
m_pDoc=(LPCPatronDoc)pObj;
m_pPage=NULL;
}
else
{
m_pDoc=NULL;
m_pPage=(LPPAGE)pObj;
}
m_punkOuter=punkOuter;
return;
}
CImpIOleItemContainer::~CImpIOleItemContainer(void)
{
return;
}
/*
* CImpIOleItemContainer::QueryInterface
* CImpIOleItemContainer::AddRef
* CImpIOleItemContainer::Release
*
* Purpose:
* IUnknown members for CImpIOleItemContainer object.
*/
STDMETHODIMP CImpIOleItemContainer::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
return m_punkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CImpIOleItemContainer::AddRef(void)
{
++m_cRef;
return m_punkOuter->AddRef();
}
STDMETHODIMP_(ULONG) CImpIOleItemContainer::Release(void)
{
--m_cRef;
return m_punkOuter->Release();
}
/*
* CImpIOleItemContainer::ParseDisplayName
*
* Purpose:
* Inherited member of IParseDisplayName that takes a string name and
* turns out a moniker for it.
*
* Parameters:
* pbc LPBC to the binding context
* pszName LPSTR to the name to parse.
* pchEaten ULONG FAR * into which to store how many characters
* we scanned in the display name.
* ppmk LPMONIKER FAR * in which to return the moniker.
*
* Return Value:
* HRESULT NOERROR if successful, error code otherwise.
*/
STDMETHODIMP CImpIOleItemContainer::ParseDisplayName(LPBC pbc, LPSTR pszName
, ULONG FAR * pchEaten, LPMONIKER FAR *ppmk)
{
*ppmk=NULL;
return ResultFromScode(E_NOTIMPL);
}
/*
* CImpIOleItemContainer::EnumObjects
*
* Purpose:
* Creates and returns an IEnumUnknown object that allows the caller
* to walk through the objects in this continer thing.
*
* Parameters:
* dwFlags DWORD specifying what kind of objects to
* enumerate.
* ppEnum LPENUMUNKNOWN FAR * into which to return the enumerator
*
* Return Value:
* HRESULT NOERROR if successful, error code otherwise.
*/
STDMETHODIMP CImpIOleItemContainer::EnumObjects(DWORD dwFlags
, LPENUMUNKNOWN FAR *ppEnum)
{
*ppEnum=NULL;
return ResultFromScode(E_NOTIMPL);
}
/*
* CImpIOleItemContainer::LockContainer
*
* Purpose:
* Establishes a lock on the container to prevent it from shutting down
* outside of user control. This is used to control the lifetime of
* the container when it's used to update a link to an embedded object
* within it. If we're unlock and the user has not taken control,
* we close.
*
* Parameters:
* fLock BOOL indicating a lock or unlock.
*
* Return Value:
* HRESULT NOERROR if successful, error code otherwise.
*/
STDMETHODIMP CImpIOleItemContainer::LockContainer(BOOL fLock)
{
/*
* This is pretty much the same implementation as
* IClassFactory::LockServer, and we can use the same lock
* count to accomplish our goal.
*/
if (fLock)
g_cLock++;
else
{
g_cLock--;
/*
* To centralize shutdown, we'll artificially increase the object
* count here and call ObjectDestroyed, which will decrement the
* count, see that there are no objects or locks, then shut down.
*/
g_cObj++;
ObjectDestroyed();
}
return NOERROR;
}
/*
* CImpIOleItemContainer::GetObject
*
* Purpose:
* Returns the requested interface pointer on an object in this
* container.
*
* Parameters:
* pszItem LPSTR to the item we must locate.
* dwSpeed DWORD identifying how long the caller is willing to wait.
* pcb LPBINDCTX providing the binding context.
* riid REFIID of the interface requested.
* ppv LPLPVOID into which to return the object.
*
* Return Value:
* HRESULT NOERROR if successful, error code otherwise.
*/
STDMETHODIMP CImpIOleItemContainer::GetObject(LPSTR pszItem, DWORD dwSpeed
, LPBINDCTX pbc, REFIID riid, LPVOID FAR *ppv)
{
DWORD dw;
char szTemp[40]; //Local assumes SS==DS
HRESULT hr=ResultFromScode(E_FAIL);
LPPAGE pPage;
LPTENANT pTenant;
LPUNKNOWN pObj;
UINT i, iCur;
*ppv=NULL;
if (m_fDoc)
{
/*
* The item name should be "Page n", so we'll do it the
* easy way: call atol on pszItem+5 (we always know that
* we'll have "Page " there since we put it there (see
* CPage::GetStorageName).
*/
lstrcpy(szTemp, (LPSTR)(pszItem+5));
dw=atol(szTemp);
i=m_pDoc->m_pPG->IPageGetFromID(dw, &pPage, FALSE);
if (-1==i)
return hr;
/*
* If we're asked for immediate speed, only do this if the
* page is already current, i.e. everything is loaded.
*/
iCur=m_pDoc->m_pPG->CurPageGet();
if (BINDSPEED_IMMEDIATE==dwSpeed && iCur!=i)
return ResultFromScode(MK_E_EXCEEDEDDEADLINE);
m_pDoc->m_pPG->CurPageSet(i);
//This will have changed to be the current page now.
if (NULL!=m_pDoc->m_pPG->m_pPageCur)
hr=m_pDoc->m_pPG->m_pPageCur->QueryInterface(riid, ppv);
}
else
{
if (FTenantFromName(pszItem, &pTenant))
{
pTenant->ObjectGet(&pObj);
/*
* If we're asked for immediate or moderate, only work
* if the object is already running.
*/
hr=IsRunning(pszItem); //This is the function below
if ((BINDSPEED_IMMEDIATE==dwSpeed
|| BINDSPEED_MODERATE==dwSpeed) && NOERROR!=hr)
hr=ResultFromScode(MK_E_EXCEEDEDDEADLINE);
else
{
//IMPORTANT: Make sure this object is running first
OleRun(pObj);
hr=pObj->QueryInterface(riid, ppv);
}
pObj->Release();
}
else
hr=ResultFromScode(MK_E_NOOBJECT);
}
return hr;
}
/*
* CImpIOleItemContainer::GetObjectStorage
*
* Purpose:
* Similar to get Object in that we have to locate the object
* described by a given name, but instead of returning any old
* interface we return a storage element.
*
* Parameters:
* pszItem LPSTR to the item we must locate.
* pcb LPBINDCTX providing the binding context.
* riid REFIID of the interface requested. Usually
* IStorage or IStream.
* ppv LPLPVOID into which to return the object.
*
* Return Value:
* HRESULT NOERROR if successful, error code otherwise.
*/
STDMETHODIMP CImpIOleItemContainer::GetObjectStorage(LPSTR pszItem
, LPBINDCTX pbc, REFIID riid, LPVOID FAR *ppv)
{
LPTENANT pTenant;
*ppv=NULL;
if (m_fDoc)